/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package views;

import chatsystem.ChatSystemControler;
import chatsystem.ChatSystemModel;
import chatsystem.Conversation;
import chatsystem.User;
import chatsystem.patternObserver.Observer;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.io.File;
import java.io.IOException;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.BorderFactory;
import javax.swing.GroupLayout;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSeparator;
import javax.swing.JTabbedPane;
import javax.swing.JTextArea;
import javax.swing.LayoutStyle;
import javax.swing.ListSelectionModel;
import javax.swing.SwingConstants;
import javax.swing.WindowConstants;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.plaf.basic.BasicButtonUI;
import protocol.AskSendFile;
import protocol.TalkID;
import protocol.TextMessage;

/**
 *
 * @author Diane
 */
public class ChatSystemConversationView extends JFrame implements Observer, WindowListener {

    private JButton btnSend;
    private JLabel jLabel1;
    private JList jList1;
    private JMenuBar jMenuBar;
    private JMenu jMenuFile;
    private JMenuItem jMenuItemInvit;
    private JMenuItem jMenuItemQuit;
    private JMenuItem jMenuItemSendFile;
    private JPanel jPanel1;
    private JScrollPane jScrollPane1;
    private JScrollPane jScrollPane2;
    private JScrollPane jScrollPane3;
    private JSeparator jSeparator1;
    private JTabbedPaneWithCloseIcons jTabbedPane1 ;
    private JTextArea textToReceive;
    private JTextArea textToSend;
    private Conversation current_conversation;
    private ArrayList<ConversationTab> list_tab_convers;

    // Instance de l'objet contrôleur
    private ChatSystemControler csc;
    private InvitConversationView invit_conversation_view;
    
    public ChatSystemConversationView(ChatSystemControler csc) {

        this.csc = csc;
        this.csc.setConversation_view(this);
        list_tab_convers = new ArrayList<ConversationTab>();
        
        this.setTitle("ChatSystemConversation");        
        initComponents();

        this.setVisible(true);
    }    
        
    private void initComponents() {

        addWindowListener(this);
        
        jScrollPane1 = new JScrollPane();
        jList1 = new JList();
        jLabel1 = new JLabel();
        jSeparator1 = new JSeparator();
        jTabbedPane1 = new JTabbedPaneWithCloseIcons();
        jPanel1 = new JPanel();
        jScrollPane2 = new JScrollPane();
        textToReceive = new JTextArea();
        jScrollPane3 = new JScrollPane();
        textToSend = new JTextArea();
        btnSend = new JButton();
        jMenuBar = new JMenuBar();
        jMenuFile = new JMenu();
        jMenuItemQuit = new JMenuItem();
        jMenuItemInvit = new JMenuItem();
        jMenuItemSendFile = new JMenuItem();

        jTabbedPane1.addChangeListener(new ChangeListener() {

            public void stateChanged(ChangeEvent e) {
               
                JTabbedPane source = (JTabbedPane)e.getSource();
                ConversationTab tab = (ConversationTab) source.getSelectedComponent();
              
                current_conversation = csc.getModel().getConversationByID(tab.getIdConvers());
                System.out.println("etat changé : "+current_conversation.getTid());
                jList1.setModel(current_conversation);
            }
        });

        jList1.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
        jList1.setSelectedIndex(0);
        
        jScrollPane1.setViewportView(jList1);

        jLabel1.setText("Ils sont là");

        jSeparator1.setOrientation(SwingConstants.VERTICAL);

        jMenuFile.setText("File");

        jMenuItemQuit.setText("Quitter la conversation");
        jMenuItemQuit.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                try {
                    jMenuItemActionPerformed(evt);
                } catch (Exception ex) {
                    System.out.println(ex);
                } 
            }
        });
        jMenuFile.add(jMenuItemQuit);

        jMenuItemInvit.setText("Inviter un contact");
        jMenuItemInvit.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                try {
                    jMenuItemActionPerformed(evt);
                } catch (Exception ex) {
                    System.out.println(ex);
                } 
            }
        });
        jMenuFile.add(jMenuItemInvit);
        
        jMenuItemSendFile.setText("Envoyer un fichier");
        jMenuItemSendFile.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                try {
                    jMenuItemActionPerformed(evt);
                } catch (Exception ex) {
                    System.out.println(ex);
                }
            }
        });
        jMenuFile.add(jMenuItemSendFile);

        jMenuBar.add(jMenuFile);

        setJMenuBar(jMenuBar);

        GroupLayout layout = new GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING)
                    .addComponent(jLabel1)
                    .addComponent(jScrollPane1, GroupLayout.PREFERRED_SIZE, 103, GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jSeparator1, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jTabbedPane1, GroupLayout.DEFAULT_SIZE, 413, Short.MAX_VALUE)
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addComponent(jLabel1)
                .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING)
                    .addComponent(jTabbedPane1, GroupLayout.DEFAULT_SIZE, 348, Short.MAX_VALUE)
                    .addComponent(jScrollPane1, GroupLayout.DEFAULT_SIZE, 348, Short.MAX_VALUE))
                .addContainerGap())
            .addComponent(jSeparator1, GroupLayout.DEFAULT_SIZE, 379, Short.MAX_VALUE)
        );

        pack();
    }

    private void jMenuItemActionPerformed(ActionEvent e) throws UnknownHostException, SocketException, IOException {
        if (e.getSource() == jMenuItemQuit) {
            /* On notifie le contrôleur qu'on quitte la conversation courante */
           csc.quitConversation(current_conversation.getTid());
           
           /* Si il y a une seule conversation, on quitte la fenetre */
           if (list_tab_convers.size()==1){
               this.dispose();
               csc.setConversation_view(null);
           } 
           else
           {
              /* Sinon on supprime l'onglet correspondant */
              int indexTab = 0;
                for (ConversationTab convers : list_tab_convers){
                    if (convers.getIdConvers() == current_conversation.getTid()){
                        System.out.println("prout"+ current_conversation.getTid());

                        indexTab=list_tab_convers.indexOf(convers);
                    }
                }
                jTabbedPane1.removeTabAt(indexTab);
                list_tab_convers.remove(indexTab);
           }  
        } else if (e.getSource() == jMenuItemInvit) {
            System.out.println("Ajouter un contact");
            invit_conversation_view = new InvitConversationView(csc);           
        }
        else if (e.getSource() == jMenuItemSendFile) {
            JFileChooser fc = new JFileChooser();
            int choix = fc.showOpenDialog(null);
            File f = fc.getSelectedFile();
            if (choix == fc.APPROVE_OPTION) {
                csc.sendFileMessage(current_conversation.getTid(), f);
            }
        }
    }  

    public void quitTabById(TalkID id) {
       /* Si c'était le seul onglet ouvert, on quitte la fenetre */
       if (list_tab_convers.size()==1){
           this.dispose();
           csc.setConversation_view(null);
       } 
       else
       {
          /* Sinon on supprime l'onglet correspondant */
          int indexTab = 0;
            for (ConversationTab convers : list_tab_convers){
                if (convers.getIdConvers() == current_conversation.getTid()){
                    System.out.println("id conversation courante : "+ current_conversation.getTid());

                     indexTab=list_tab_convers.indexOf(convers);
                }
            }
            jTabbedPane1.removeTabAt(indexTab);
            list_tab_convers.remove(indexTab);
       } 
    }
    
    public void quitTab() throws UnknownHostException, SocketException, IOException{    
       /* On notifie le contrôleur qu'on quitte la conversation courante */                 
       csc.quitConversation(current_conversation.getTid());

       /* Si il y a une seule conversation, on quitte la fenetre */
       if (list_tab_convers.size()==1){
           this.dispose();
           csc.setConversation_view(null);
       } 
       else
       {
          /* Sinon on supprime l'onglet correspondant */
          int indexTab = 0;
            for (ConversationTab convers : list_tab_convers){
                if (convers.getIdConvers() == current_conversation.getTid()){
                    System.out.println("id conversation courante : "+ current_conversation.getTid());

                     indexTab=list_tab_convers.indexOf(convers);
                }
            }
            jTabbedPane1.removeTabAt(indexTab);
            list_tab_convers.remove(indexTab);
       }           
    }

     /* Listener du bouton Se connecter */
    class ButtonListener implements ActionListener{

        public void actionPerformed(ActionEvent e) {
            // CLIC sur le bouton Send
            if (e.getSource() == btnSend) {
                try {
                    /* Préparation du paquet à envoyer
                     * Contient l'id de la conversation courante et le texte
                     */
                   
                    TalkID id = csc.getConversation_view().getCurrent_conversation().getTid();
                    TextMessage msg = new TextMessage(id, textToSend.getText());
                    csc.sendTextMessage(id, msg);
                    /* On rafraîchit l'affichage */
                    textToSend.setText("");
                    textToReceive.append("\nMe say "+msg.getMsgContent());
                } catch (Exception ex) {
                    System.out.println(ex);
                }
            }
        }
    }

    public void addNewTalk(TalkID id) {
        ConversationTab tab = new ConversationTab(id, this.csc);
        list_tab_convers.add(tab);
        jTabbedPane1.addTab(id.toString(), tab,list_tab_convers.indexOf(tab));
    }

    public void displayTextMessage(TextMessage msg, User fromUser) {
        TalkID id = msg.getTid();
        String s = msg.getMsgContent();
        getTabByTalkID(id).displayTextMessage(s, fromUser);
    }
    
    public void displayAskSendFile(AskSendFile asf, User u) throws SocketException, IOException {
        int option = JOptionPane.showConfirmDialog(null, u.getName()+" souhaite vous envoyer le fichier :\n"+asf.getFileName()+" ; taille : "+asf.getFileSize(), "Demande de permission", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE);
        if(option == JOptionPane.YES_OPTION) {
            csc.acceptFile(asf, u);
        } else if(option == JOptionPane.NO_OPTION) {
            csc.declineFile(asf, u);
        }
    }
    
    public void displayUserJoinMessage(User newUser, TalkID id) {
            
        String s ="\n ===> "+newUser.getName()+" has joined the conversation";   
        getTabByTalkID(id).displayTextMessage(s, newUser); 
    }
    
    public void displayQuitMessage(User u, TalkID id) {
            
        String s ="\n ===> "+u.getName()+" has left the conversation";   
        getTabByTalkID(id).displayTextMessage(s, u); 
    }
    

    private ConversationTab getTabByTalkID(TalkID id) {
        ConversationTab tab = null;
        for (ConversationTab t : list_tab_convers) {
            if (t.getIdConvers().equals(id)) tab = t;
        }
        return tab;
    }

    
     /**
     * @return the current_conversation
     */
    public Conversation getCurrent_conversation() {
        return current_conversation;
    }
    
    public void update(ChatSystemModel cs) {
        
    }

    public void windowOpened(WindowEvent e) {
        
    }

    public void windowClosing(WindowEvent e) {
        csc.setConversation_view(null);
        for (ConversationTab t : list_tab_convers) {
            try {                
                csc.quitConversation(t.getIdConvers());
            } catch (Exception ex) {
                System.out.println(ex);
            }
        }
    }

    public void windowClosed(WindowEvent e) {
        
    }

    public void windowIconified(WindowEvent e) {
        
    }

    public void windowDeiconified(WindowEvent e) {
        
    }

    public void windowActivated(WindowEvent e) {
        
    }

    public void windowDeactivated(WindowEvent e) {
        
    }  
    
    /////////////////GESTION DES TAB AVEC LES BOUTONS CLOSE//////////////////
    public class JTabbedPaneWithCloseIcons extends javax.swing.JTabbedPane{
    JTabbedPaneWithCloseIcons moi; //pour avoir acces au l'element this dans les class internes
	public JTabbedPaneWithCloseIcons() {
		super();
        moi =this;
	}
 
	public void addTab(String title, Component component,int endroit) {
            super.addTab(title, component); //on ajoute une Tab à JTabbedPane
            super.setTabComponentAt(endroit, new CloseTabPanel(title)); //on applique le closeTabPanel a l'element "endroit"
            
	}
 
		//fonction qui permet d'affiché le bouton close
        public void afficheIconAt(int endroit){
            ((CloseTabPanel)moi.getTabComponentAt(endroit)).afficheIcon(true);
        }
		//fonction qui permet d'enlever le bouton close
        public void cacheIconAt(int endroit){
            ((CloseTabPanel)moi.getTabComponentAt(endroit)).afficheIcon(false);
        }
 
 
 
class CloseTabPanel extends JPanel{
        JButton button; 
 
	//constructeur sans boolean  qui de base met un bouton close
    public CloseTabPanel(String titre) {
            super(new FlowLayout(FlowLayout.LEFT, 0, 0));
            setOpaque(false);
            JLabel label = new JLabel(titre);
            add(label);
            button = new TabButton();
            add(button);
            setBorder(BorderFactory.createEmptyBorder(2, 0, 0, 0));
	}
	//constructeur avec boolean  qui permet de choisir si oui ou non on veux un bouton close
		public CloseTabPanel(String titre, boolean b){
            super(new FlowLayout(FlowLayout.LEFT, 0, 0));
            setOpaque(false);
            JLabel label = new JLabel(titre);
            add(label);
            button = new TabButton();
            if(b){
            add(button);
            }
            //add more space to the top of the component
            setBorder(BorderFactory.createEmptyBorder(2, 0, 0, 0));
        }
        //permet d'afficher ou cacher le bouton close
        public void afficheIcon(boolean b){
            if(b){
                if(this.getComponentCount()==1)
                    this.add(button);
            }else{
                if(this.getComponentCount()>1)
                    this.remove(button);
            }
        }
}
class TabButton extends JButton implements ActionListener {
    public TabButton() {
            int size = 17;
            setPreferredSize(new Dimension(size, size));
            setToolTipText("Fermer cet onglet");
            //Make the button looks the same for all Laf's
            setUI(new BasicButtonUI());
            //Rends le bouton transparent
            setContentAreaFilled(false);
            //pas besoin d'avoir le focus
            setFocusable(false);
            setBorder(BorderFactory.createEtchedBorder());
            setBorderPainted(false);
            addActionListener(this);            
        }
		/*
		* fonction qui ferme l'onglet du bouton close sur lequel on a cliqué
		*/
    public void actionPerformed(ActionEvent e) {
            int X = new Double(((JButton)e.getSource()).getMousePosition().getX()).intValue();
            int Y = new Double(((JButton)e.getSource()).getMousePosition().getY()).intValue();
 
            int i = moi.getUI().tabForCoordinate((JTabbedPane)moi, X,Y);
            if (i != -1) {
                    try {
                        quitTab();
                    } catch (UnknownHostException ex) {
                        Logger.getLogger(ChatSystemConversationView.class.getName()).log(Level.SEVERE, null, ex);
                    } catch (SocketException ex) {
                        Logger.getLogger(ChatSystemConversationView.class.getName()).log(Level.SEVERE, null, ex);
                    } catch (IOException ex) {
                        Logger.getLogger(ChatSystemConversationView.class.getName()).log(Level.SEVERE, null, ex);
                    }
            }
        }
 
        //we don't want to update UI for this button
        public void updateUI() {
        }
 
        //dessine la croix dans le bouton
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2 = (Graphics2D) g.create();
            //shift the image for pressed buttons
            if (getModel().isPressed()) {
                g2.translate(1, 1);
            } 
            g2.setStroke(new BasicStroke(2));
            g2.setColor(Color.BLACK);
            if (getModel().isRollover()) {
                g2.setColor(Color.MAGENTA);
            }            
            int delta = 6;
            g2.drawLine(delta, delta, getWidth() - delta - 1, getHeight() - delta - 1);
            g2.drawLine(getWidth() - delta - 1, delta, delta, getHeight() - delta - 1);
            g2.dispose();
        }
    }
}
    
    
    
    
    
}





